#include "directed_community.h"



Directed_Community::Directed_Community(const string& in_filename,
                                       const double precision, 
                                       const double gamma, 
                                       bool reproducibility,
                                       bool renumbering, 
                                       bool randomized) 
{
    this->g          = new Directed_Graph(in_filename, reproducibility, renumbering);
    this->precision  = precision;
    this->gamma      = gamma;
    this->randomized = randomized;
    init_attributes();
}


Directed_Community::Directed_Community(const vector<vector<pair<unsigned int, double>>>& adj_list,
                                       const double precision,
                                       const double gamma,
                                       bool reproducibility,
                                       bool renumbering,
                                       bool randomized)
{
    this->g = new Directed_Graph(adj_list, reproducibility, renumbering);
    this->precision = precision;
    this->gamma = gamma;
    this->randomized = randomized;
    init_attributes();
}


Directed_Community::Directed_Community(const Directed_Graph& graph,
                                       const double precision, 
                                       const double gamma, 
                                       bool reproducibility, 
                                       bool renumbering, 
                                       bool randomized) 
{
    this->g          = new Directed_Graph(graph);
    this->precision  = precision;
    this->gamma      = gamma;
    this->randomized = randomized;
    init_attributes();
}

void Directed_Community::init_attributes(void)
{
    this->size = g->nodes;
    this->node_to_community.resize(this->size);
    this->communities_arcs.resize(this->size);

    for (unsigned int i = 0; i < this->size; i++) 
    {
        this->node_to_community[i] = i;

        // 至少一次聚合后，社区内的总边数对应于节点i的加权自环、加权出/入度
        this->communities_arcs[i].total_arcs_inside    = g->count_selfloops(i);
        this->communities_arcs[i].total_outcoming_arcs = g->weighted_out_degree(i);
        this->communities_arcs[i].total_incoming_arcs  = g->weighted_in_degree(i);
    }
}

Directed_Community::~Directed_Community()
{
    delete this->g;
    delete this->community_graph;
}


unsigned int Directed_Community::renumber_communities(const Directed_Community& c,
                                                      vector<int>& renumber)
{
    size_t size = c.get_size();
    for (unsigned int node = 0; node < size; node++)
    {
        ++renumber[c.get_community(node)];
    }

    unsigned int f = 0;
    for (unsigned int i = 0; i < size; i++)
    {
        if (renumber[i] != -1)
        {
            renumber[i] = f++;
        }
    }
    return f;
}

void Directed_Community::update_levels(const Directed_Community& c,
                                       vector<vector<int>>& levels,
                                       int level)
{
    vector<int> renumber(c.get_size(), -1);
    renumber_communities(c, renumber);
    for (unsigned int i = 0; i < c.get_size(); i++)
    {
        levels[level].push_back(renumber[c.get_community(i)]);
    }
}



//!  更新在删除一个节点之后,从社区出度、入度以及社区自环的总数
void Directed_Community::remove(Directed_Community& c,
                                const unsigned int& node,
                                const int& comm,
                                const double& dnodecomm,
                                const double& weighted_out_degree,
                                const double& weighted_in_degree)
{
    assert(node < c.size);
    c.communities_arcs[comm].total_outcoming_arcs -= weighted_out_degree; // 从社区comm的total_outcoming_arcs（总出边数）中减去节点的带权出度
    c.communities_arcs[comm].total_incoming_arcs  -= weighted_in_degree;   // 从社区comm的total_incoming_arcs（总入边数）中减去节点的带权入度。
    c.communities_arcs[comm].total_arcs_inside    -= dnodecomm;              // 从社区comm的total_arcs_inside（社区内部边的权重总和）中减去dnodecomm。
    c.node_to_community[node] = -1;                                       //将节点node在社区映射node_to_community中的值设置为 - 1，表示该节点已经从任何社区中移除。
}

//!  更新在插入一个节点之后,从社区出度、入度以及社区自环的总数
void Directed_Community::insert(Directed_Community& c,
                                const unsigned int& node,
                                const int& comm,
                                const double& dnodecomm,
                                const double& weighted_out_degree,
                                const double& weighted_in_degree)
{
    assert(node < c.size);
    c.communities_arcs[comm].total_outcoming_arcs += weighted_out_degree;
    c.communities_arcs[comm].total_incoming_arcs  += weighted_in_degree;
    c.communities_arcs[comm].total_arcs_inside    += dnodecomm;
    c.node_to_community[node] = comm;
}

//!  计算将节点移除给定社区时的模块度变化
double Directed_Community::gain_from_removal(const Directed_Community& c,
                                             const unsigned int& node,
                                             const int& comm,
                                             const double& dnodecomm,
                                             const double& weighted_out_degree,
                                             const double& weighted_in_degree)
{
    assert(node < c.size);
    double totc_out = c.communities_arcs[comm].total_outcoming_arcs;
    double totc_in  = c.communities_arcs[comm].total_incoming_arcs;
    double m = (c.community_graph)->get_total_weight();
    return ((-dnodecomm / m) + 
            c.gamma * 
            ((weighted_out_degree * totc_in + weighted_in_degree * totc_out)) / (m * m));// delt_Q

}

//!  计算将节点插入给定社区时的模块度增益
double Directed_Community::gain_from_insertion(const Directed_Community& c,
                                               const unsigned int& node,
                                               const int& comm,
                                               const double& dnodecomm,
                                               const double& weighted_out_degree,
                                               const double& weighted_in_degree)
{
    assert(node < c.size);
    double totc_out = c.communities_arcs[comm].total_outcoming_arcs + weighted_out_degree;
    double totc_in  = c.communities_arcs[comm].total_incoming_arcs  + weighted_in_degree;
    double m = (c.community_graph)->get_total_weight();
    return ((dnodecomm / m) - 
            c.gamma * 
            ((weighted_out_degree * totc_in + weighted_in_degree * totc_out)) / (m * m));
}

//!  计算给定节点在图中所有相邻社区的权重，并将这些社区的位置（通过它们的ID）
/* 
*    存储在 positions_neighboring_communities 数组中。
*    如果图是加权的，权重基于边的权重；否则，每个邻居的权重默认为 1.0
*/ 
void Directed_Community::list_neighboring_communities(const unsigned int& node,
                                                      const Directed_Community& c,
                                                      vector<double>& neighbor_weight,
                                                      vector<unsigned int>& positions_neighboring_communities,
                                                      unsigned int& neighboring_communities)
{
    // 将之前存储的相邻社区权重重置为 -1.0，作为未初始化的标记
    for (unsigned int i = 0; i < neighboring_communities; i++)
    {
        neighbor_weight[positions_neighboring_communities[i]] = -1.f;
    }

    size_t p = (c.community_graph)->out_neighbors(node);
    unsigned int deg = (c.community_graph)->out_degree(node);

    // 每个节点的第一个相邻社区是其自身所在的社区
    positions_neighboring_communities[0] = c.get_community(node);
    neighbor_weight[positions_neighboring_communities[0]] = 0;
    neighboring_communities = 1;

    // 节点的每个出邻居。对于每个邻居，获取其社区和权重
    for (unsigned int i = 0; i < deg; ++i)
    {
        // 获取节点i的邻居、它们所属的社区以及相应的度
        unsigned int neigh = (c.community_graph)->get_out_neighbor(p + i);
        int neigh_comm = c.get_community(neigh);
        double neigh_w = ((c.community_graph)->is_weighted()) ? (c.community_graph)->get_weighted_out_neighbor(p + i) : 1.f;

        if (neigh != node) 
        {
            // 如果社区是首次发现的
            if (neighbor_weight[neigh_comm] == -1.f)
            {
                neighbor_weight[neigh_comm] = 0.f;
                positions_neighboring_communities[neighboring_communities++] = neigh_comm;
            }
            // 对于每个邻居，其社区权重增加，增量是该邻居的权重
            //（如果是加权图，则是边的权重；否则默认为 1.0）
            neighbor_weight[neigh_comm] += neigh_w;
        }
    }

    // 以类似的方式处理节点的入邻居，即指向节点的边
    size_t p_in = (c.community_graph)->in_neighbors(node);
    unsigned int deg_in = (c.community_graph)->in_degree(node);

    for (unsigned int i = 0; i < deg_in; ++i)
    {
        unsigned int neigh_in = (c.community_graph)->get_in_neighbor(p_in + i);
        int neigh_comm_in     = c.get_community(neigh_in);
        double neigh_w_in     = ((c.community_graph)->is_weighted()) ? (c.community_graph)->get_weighted_in_neighbor(p_in + i) : 1.f;

        if (neigh_in != node)
        {
            if (neighbor_weight[neigh_comm_in] == -1.f)
            {
                neighbor_weight[neigh_comm_in] = 0.f;
                positions_neighboring_communities[neighboring_communities++] = neigh_comm_in;
            }
            neighbor_weight[neigh_comm_in] += neigh_w_in;
        }
    }
}




/* no test */
void Directed_Community::init_partition(string filename)
{
    ifstream finput;
    finput.open(filename, fstream::in);
    //finput.open(filename);
    assert(finput.rdstate() == ios::goodbit);

    unsigned int node, comm;
    while (finput >> node >> comm) 
    {
        vector<unsigned int> positions_neighboring_communities(this->size);
        vector<double> neighbor_weight(this->size, -1);

        int old_comm = this->node_to_community[node];
        unsigned int neighboring_communities = 0;
        list_neighboring_communities(node, 
                                     *this, 
                                     neighbor_weight, 
                                     positions_neighboring_communities, 
                                     neighboring_communities);

        remove(*this, 
                node, 
                old_comm, 
                neighbor_weight[old_comm], 
                (this->g)->weighted_out_degree(node), 
                (this->g)->weighted_in_degree(node));

        unsigned int best_community = 0;
        double best_nbarcs          = 0.;
        unsigned int i;

        for (i = 0; i < size; ++i) 
        {
            best_community  = positions_neighboring_communities[i];
            best_nbarcs     = neighbor_weight[positions_neighboring_communities[i]];
            if (best_community == comm) 
            {
                insert(*this, 
                        node, 
                        best_community, 
                        best_nbarcs, 
                        (this->g)->weighted_out_degree(node), 
                        (this->g)->weighted_in_degree(node));
                break;
            }
        }
        if (i == neighboring_communities)
        {
            insert(*this, 
                    node,
                    comm, 
                    0.f, 
                    (this->g)->weighted_out_degree(node), 
                    (this->g)->weighted_in_degree(node));
        }
    }
    finput.close();
}

void Directed_Community::display(void)
{
    for (unsigned int i = 0; i < size; i++)
    {
        cout << " " << (this->g)->correspondance[i] << "/" << node_to_community[i] << "/"
             << this->communities_arcs[i].total_arcs_inside << "/"
             << this->communities_arcs[i].total_outcoming_arcs << "/" << this->communities_arcs[i].total_incoming_arcs;
    }
    cout << endl;
}

// 计算整个图的模块度
double Directed_Community::modularity(void)
{
    double q = 0.;
    double m = g->get_total_weight();
    for (unsigned int i = 0; i < size; i++) 
    {
        if (this->communities_arcs[i].total_incoming_arcs > 0 || this->communities_arcs[i].total_outcoming_arcs > 0) 
        {
            double total_outcoming_arcs_var = (this->communities_arcs[i].total_outcoming_arcs) / m;
            double total_incoming_arcs_var  = this->communities_arcs[i].total_incoming_arcs / m;
            q += this->communities_arcs[i].total_arcs_inside / m - (total_outcoming_arcs_var * total_incoming_arcs_var);
        }
    }
    return q;
}

void Directed_Community::display_partition(const bool& improve, 
                                           map<unsigned int, vector<unsigned int>>& best_partition)
{
    //存储每一次的模块划分结果
    static vector<vector<int>> levels;
    vector<int> community(Directed_Community::size, -1);

    vector<int> renumber(size, -1);                    //存储节点聚合后的节点编号
    renumber_communities(*this, renumber);
   
    cout << -1 << " " << -1 << endl;                    // 新的模块划分层次开始标记
    for (unsigned int i = 0; i < size; i++)
    {
        //cout << (this->community_graph)->correspondance[i] << " "       // 输出每一层级的社区划分情况
        //     << renumber[this->node_to_community[i]] << endl;
        community[(this->community_graph)->correspondance[i]] =         // 保存每一层级的社区划分结果
        renumber[this->node_to_community[i]];
    }

    
    //判断模块度是否有提升
    if (improve == true)
    {
        levels.push_back(community);
    }
    else if(levels.size() >= 1)  // 通过映射，确定聚合前每个节点的最终社区编号（levels[0]），可以通过DFS改进
    {
        for (int level = levels.size() - 2; level >= 0; level--)
        {
            for (int community = 0; community < levels[level].size(); community++)
            {
                levels[level][community] = levels[level + 1][levels[level][community]];
            }
        }
        for (int node_to_community = 0; node_to_community < levels[0].size(); node_to_community++)
        {
            best_partition[levels[0][node_to_community]].push_back(node_to_community);
        }
    }
}

void Directed_Community::partition_to_graph(void)
{
    // 社区重新编号
    vector<int>  renumber(size, -1);
    unsigned int f = renumber_communities(*this, renumber);

    //二维向量comm_nodes，其大小为新社区的数量f。这个二维向量将用于存储每个社区中的节点列表。
    vector<vector<int>> comm_nodes(f);     
    for (unsigned int node = 0; node < size; ++node)
    {
        //遍历所有节点，使用renumber向量将每个节点的社区编号映射到新的编号，
        //并将节点添加到对应社区的节点列表中
        comm_nodes[renumber[this->node_to_community[node]]].push_back(node);
    }

    Directed_Graph* g2 = new Directed_Graph();
    g2->nodes          = comm_nodes.size();
    g2->weighted       = true;

    // 设置新图的对应关系(Louvain算法中的聚合操作)
    for (unsigned int i = 0; i < g2->nodes; i++)
    {
        g2->correspondance.push_back(i);
    }    

    g2->outdegrees.resize(g2->nodes);
    g2->indegrees.resize(g2->nodes);

    unsigned int out_neighbor, out_neighboring_community;
    double       out_weight;
    unsigned int in_neighbor, in_neighboring_community;
    double       in_weight;

    // 计算社区合并为超级节点后的信息
    for (size_t comm = 0; comm < g2->nodes; comm++) 
    {
        map<int, double> m_out, m_in;
        size_t comm_size = comm_nodes[comm].size();
        for (unsigned int node = 0; node < comm_size; node++) 
        {
            // Out-neighbors
            size_t p = (this->community_graph)->out_neighbors(comm_nodes[comm][node]);
            unsigned int deg = (this->community_graph)->out_degree(comm_nodes[comm][node]);
            // 寻找每个出度邻居的社区，并存储/更新加权出度
            for (unsigned int i = 0; i < deg; i++) 
            {
                out_neighbor              = (this->community_graph)->outcoming_arcs[p + i];
                out_neighboring_community = renumber[this->node_to_community[out_neighbor]];
                out_weight                = ((this->community_graph)->weighted) ? (this->community_graph)->outcoming_weights[p + i] : 1.f;

                auto it_out               = m_out.find(out_neighboring_community);
                if (it_out == m_out.end())
                {
                    m_out.insert(make_pair(out_neighboring_community, out_weight));
                }
                else
                {
                    it_out->second += out_weight;
                }
            }

            // In-neighbors
            size_t p_in = (this->community_graph)->in_neighbors(comm_nodes[comm][node]);
            deg         = (this->community_graph)->in_degree(comm_nodes[comm][node]);
            // 寻找每个入度邻居的社区，并存储/更新加权入度
            for (unsigned int i = 0; i < deg; i++) 
            {
                in_neighbor              = (this->community_graph)->incoming_arcs[p_in + i];
                in_neighboring_community = renumber[this->node_to_community[in_neighbor]];
                in_weight                = ((this->community_graph)->weighted) ? (this->community_graph)->incoming_weights[p_in + i] : 1.f;

                auto it_in               = m_in.find(in_neighboring_community);
                if (it_in == m_in.end())
                {
                    m_in.insert(make_pair(in_neighboring_community, in_weight));
                }       
                else
                {
                    it_in->second += in_weight;
                }                   
            }
        }

        // 根据先前计算的权重构建超级节点的加权出/入度
        g2->outdegrees[comm] = (comm == 0) ? m_out.size() : g2->outdegrees[comm - 1] + m_out.size();
        g2->arcs            += m_out.size();

        for (auto it_out = m_out.begin(); it_out != m_out.end(); it_out++) 
        {
            g2->total_weight += it_out->second;
            g2->outcoming_arcs.push_back(it_out->first);
            g2->outcoming_weights.push_back(it_out->second);
        }

        g2->indegrees[comm] = (comm == 0) ? m_in.size() : g2->indegrees[comm - 1] + m_in.size();

        for (auto it_in = m_in.begin(); it_in != m_in.end(); it_in++) 
        {
            g2->incoming_arcs.push_back(it_in->first);
            g2->incoming_weights.push_back(it_in->second);
        }
    }

    // 利用图g2更新图属性
    delete this->community_graph;
    this->community_graph = g2;

    // 利用g2更新其他属性
    this->size = this->community_graph->nodes;
    this->node_to_community.resize(this->size);

    for (unsigned int i = 0; i < this->size; i++) 
    {
        this->node_to_community[i]                     = i;
        this->communities_arcs[i].total_arcs_inside    = this->community_graph->count_selfloops(i);
        this->communities_arcs[i].total_outcoming_arcs = this->community_graph->weighted_out_degree(i);
        this->communities_arcs[i].total_incoming_arcs  = this->community_graph->weighted_in_degree(i);
    }
}

bool Directed_Community::one_level(double& modularity)
{
    int nb_moves              = 0;
    bool improvement          = false;
    double current_modularity = this->modularity();

    // 处理图上节点的顺序
    vector<int> random_order(size);
    for (unsigned int i = 0; i < size; ++i)
    {
        random_order[i] = i;
    }  

    // randomized: if randomized = true, Louvain算法的每次计算结果可能会不同
    if (randomized) 
    {
        unsigned seed = std::chrono::system_clock::now().time_since_epoch().count();
        shuffle(random_order.begin(), random_order.end(), std::default_random_engine(seed));
    }

    // 包含相邻社区权重和位置的Vectors
    vector<double> neighbor_weight(this->size, -1);
    vector<unsigned int> positions_neighboring_communities(size);

    unsigned int neighboring_communities = 1;
    double total_increase = 0.;

    do {
        nb_moves       = 0;
        total_increase = 0.;

        // 对于每个节点：将其从当前社区中移除，并将其插入到最佳社区中
        for (unsigned int node_tmp = 0; node_tmp < size; node_tmp++) 
        {
            int node                   = random_order[node_tmp];
            int node_community         = this->node_to_community[node];
            double weighted_out_degree = (this->community_graph)->weighted_out_degree(node);
            double weighted_in_degree  = (this->community_graph)->weighted_in_degree(node);
            double self_loops          = (this->community_graph)->count_selfloops(node);

            // 计算当前节点的所有相邻社区（这些社区的数量存储在neighboring_communities中）
            list_neighboring_communities(node, 
                                         *this, 
                                         neighbor_weight, 
                                         positions_neighboring_communities, 
                                         neighboring_communities);

            // 计算将节点移除当前社区后，该社区的模块度变化
            double removal = gain_from_removal(*this, 
                                                node, 
                                                node_community, 
                                                neighbor_weight[node_community], 
                                                weighted_out_degree, 
                                                weighted_in_degree);
            remove(*this, 
                    node, 
                    node_community, 
                    neighbor_weight[node_community] + self_loops,
                    weighted_out_degree, 
                    weighted_in_degree);

            int best_community   = node_community;
            double best_nbarcs   = neighbor_weight[node_community];
            double best_increase = 0.;

            // 计算将节点挨个插入邻居节点后的模块度变化，
            // 注意：会遍历所有邻居，包括上一步中所移出的那个节点，以此来判断是否针对从上一步节点移出插入新的节点
            for (unsigned int i = 0; i < neighboring_communities; i++)
            {
                // 计算插入节点后获得的模块度
                double insertion = gain_from_insertion(*this, 
                                                        node, 
                                                        positions_neighboring_communities[i], 
                                                        neighbor_weight[positions_neighboring_communities[i]], 
                                                        weighted_out_degree, 
                                                        weighted_in_degree);
                double increase  = insertion + removal;

                // 找到遍历该节点邻居，且模块度增幅最大的邻居的编号
                if (increase > best_increase) 
                {
                    best_community = positions_neighboring_communities[i];
                    best_nbarcs    = neighbor_weight[best_community];
                    best_increase  = increase;
                }
            }
            // 将该节点插入模块度增益最大的邻居节点
            // 注意：有可能出现遍历完之后，模块度增幅最大的仍然可能是之前所移除的邻居节点
            insert(*this, 
                    node, 
                    best_community, 
                    best_nbarcs + self_loops, 
                    weighted_out_degree, 
                    weighted_in_degree);

            // 模块度增幅最大的邻居节点不是原来所移出的邻居节点，代表找到了更合适的模块合并
            if (best_community != node_community) 
            {
                total_increase += best_increase;
                improvement     = true;
                ++nb_moves;
            }
        }
        current_modularity += total_increase;

    } while (nb_moves > 0 && total_increase > precision);

    modularity = current_modularity;
    return improvement;
}

map<unsigned int, unsigned int> Directed_Community::get_level(int level)
{
    assert(level >= 0 && level < (int)this->levels.size());
    vector<int> n2c(this->g->nodes);
    map<unsigned int, unsigned int> lvl;

    for (unsigned int i = 0; i < this->g->nodes; i++)
    {
        n2c[i] = i;
    }

    for (int l = 0; l < level; l++)
    {
        for (unsigned int node = 0; node < this->g->nodes; node++)
        {
            n2c[node] = this->levels[l][n2c[node]];
        }
    }

    for (unsigned int node = 0; node < this->g->nodes; node++)
    {
        lvl[(this->g)->correspondance[node]] = n2c[node];
    }
    return lvl;
}

map<unsigned int, unsigned int> Directed_Community::get_last_level(void)
{
    return get_level(levels.size() - 1);
}

void Directed_Community::print_level(int level)
{
    assert(level >= 0 && level < (int)this->levels.size());
    vector<int> n2c(this->g->nodes);    //存储每个节点的社区归属

    for (unsigned int i = 0; i < this->g->nodes; i++)
    {
        n2c[i] = i;                     //将每个节点的初始社区归属设为它自己的索引
    }

    for (int l = 0; l < level; l++)     // 遍历从 0 到 level-1 的所有层级
    {
        for (unsigned int node = 0; node < this->g->nodes; node++)
        {
            n2c[node] = this->levels[l][n2c[node]]; // 更新节点 node 在当前层级 l 的社区归属
        }  
    }

    for (unsigned int node = 0; node < this->g->nodes; node++)
    {
        cout << (this->g)->correspondance[node] << " " << n2c[node] << endl;
    }
}

int Directed_Community::run(map<unsigned int, vector<unsigned int>>& best_partition,
                            bool verbose,
                            const int& display_level,
                            const string& filename_part)
{
    int level  = 0;
    double mod = this->modularity();
    vector<int> corres(0);

    bool improvement = true;
    if (filename_part != "")
    {
        this->init_partition(filename_part);
    }
    this->community_graph = new Directed_Graph(*(this->g));
    this->init_attributes();
    do {
        if (verbose) 
        {
            cerr << "level " << level << ":\n";
            cerr << "  network size: " <<
                this->community_graph->get_nodes() << " nodes, " <<
                this->community_graph->get_arcs() << " arcs, " <<
                this->community_graph->get_total_weight() << " weight." << endl;
        }

        // Directed Louvain 主要流程
        double new_mod = 0;
        improvement    = this->one_level(new_mod);
        // Maintaining levels
        levels.resize(++level);
        update_levels(*this, levels, level - 1);
        if ((level == display_level || display_level == -1))
        {
            this->display_partition(improvement, best_partition);
        }
        // 社区聚合（Louvain算法的第二阶段）
        this->partition_to_graph();
        if (verbose)
        {
            cerr << "  modularity increased from " << mod << " to " << new_mod << endl;
        }

        mod = new_mod;
        // 如果提供了划分信息，则至少再执行一次计算
        if (filename_part != "" && level == 1)
        {
            improvement = true;
        }
    } while (improvement);
    if (display_level == -2)
    {
        print_level(levels.size() - 1);
    }
    return level;
}

void Directed_Community::print_final_result(map<unsigned int, vector<unsigned int>>& result)
{
    // 提取（最小组件值，组件列表）的配对，用于排序模块
    vector<pair<unsigned int, vector<unsigned int>>> temp;
    for (const auto& entry : result)
    {
        // 每个模块的最小组件值是排序后vector的第一个元素
        unsigned int minComponent = entry.second.front();
        temp.emplace_back(minComponent, entry.second);
    }

    // 按最小组件值升序排序，确定新模块编号的顺序
    sort(temp.begin(), temp.end(),
         [](const auto& a, const auto& b) 
         {
            return a.first < b.first; // 按最小组件值从小到大排序
         });

    // 生成新的模块映射（新编号从0开始）
    result.clear(); // 清除原有数据
    for (size_t i = 0; i < temp.size(); ++i)
    {
        result[i] = temp[i].second; // 新编号为0,1,2...，对应排序后的组件列表
    }

    // 打印排序后的结果
    for (const auto& module : result)
    {
        cout << "Module " << module.first << ": ";
        for (unsigned int node : module.second)
        {
            cout << node  + 1 << ", ";
        }
        cout << "\nThere are " << module.second.size() << " component(s) in the sub-module.\n\n";
    }
}